# Copyright (C) 2006  Apptility LLC  http://www.apptility.com
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
require 'digest/md5'
class AjubySugarcrmPipe

    require 'integration/ajuby_soap_box'
    require 'integration/service_result'
    
    ADAPTER_STRING_CONST = "AjubySugarcrmAdapter"
    
     def init_config_settings
      @mashup_node = MashupNode.find_by_name('sugarcrm') 
      @SCRM_CONFIG = Hash.new()
      @SCRM_CONFIG['username']=@mashup_node.username
      @SCRM_CONFIG['password']=AjubyTools.base64decode(@mashup_node.password)
      @SCRM_CONFIG['debug_soap']=@mashup_node.debug_soap
      @SCRM_CONFIG['records_size']=@mashup_node.records_size
      @SCRM_CONFIG['wsdl_url']=@mashup_node.wsdl_url
            
      #AjubyLogger.logInfo("@SCRM_CONFIG<<<< : #{@SCRM_CONFIG}")
     end
            
     def initialize 
       init_config_settings
       @debug = @SCRM_CONFIG['debug_soap']
       
       @login_context = LoginContext.new()
       @login_context.wsdl_url = @SCRM_CONFIG['wsdl_url']
       @login_context.login_user_name = @SCRM_CONFIG['username']
       @login_context.login_password = @SCRM_CONFIG['password']
             
       @records_size = @SCRM_CONFIG['records_size']
       #AjubyLogger.logInfo("BF:@login_context.wsdl_url: #{@login_context.wsdl_url}")
     end
          
     def login()
       begin
         service = AjubySoapBox.connect(login_context.wsdl_url, debug_soap)
         
         u = @login_context.login_user_name
         p = Digest::MD5.hexdigest(@login_context.login_password)
         ua = {"user_name" => u,"password" => p}
         
         @login_result = service.login(ua,nil)
        
         if @login_result.error.number.to_i != 0 
    		AjubyLogger.logInfo("failed to login - #{@login_result.error.description}")
    		 return AjubySoapBox::ServiceResult.new(AjubySoapBox::Codes::COULD_NOT_CONNECT,nil,@login_result.error.description)
		 end
                     
         session_id = @login_result.id

	     user_id = service.get_user_id(@login_result.id)
	     
	     server_version = service.get_server_version
	               
         set_post_login_data(@login_result,service)
         
         # Create header handler for consecutive calls
         @header_handler_obj = PostLoginHeader.get_header(login_context.session_id)
         #AjubyLogger.logInfo("service: #{service} | debug_soap: #{debug_soap} | session_id: #{login_context.session_id}| \n server_url: #{login_context.server_url} | user_id: #{login_context.user_id}")
         return AjubySoapBox::ServiceResult.new(AjubySoapBox::Codes::CONNECTED_SUCCESSFULLY, @login_result , "Connected successfully to SugarCRM")
       rescue Exception => e
          AjubyLogger.logInfo("##################SugarCRM Adapter failed to connect: #{e.message}")
          return AjubySoapBox::ServiceResult.new(AjubySoapBox::Codes::COULD_NOT_CONNECT,nil, e.message)
       end          
    end
  
   
    def get_modules_list
      begin
        service = connect
         
        return service.get_available_modules(login_context.session_id)
       
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: get_modules_list call failed : " << e.message)
      end
          
    end  

    def get_module_records(size, module_name)
      # options would be the array of fields querying, if options null get *
      # module_name = Contact , Account etc
      # size = number of records restored, if not specified default it from yml file
      begin
        service = connect
        
        if size == nil
            size = records_size
        end
        options = Array.new()
        options.push("name")
        @query_str = build_query_str_from_options(options, module_name)   
        
        @global_resp_object = service.get_entry_list(login_context.session_id,module_name,"","",0,"",size,0)#query({"queryString"=>@query_str})
      
        return @global_resp_object
       
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: get_module_records call failed : " << e.message)
      end
      
    end  

   def get_user_records(size, module_name,id)
     
      begin
        service = connect
        
        if size == nil
            size = records_size
        end
          
        @module = module_name.downcase
        @user_list = service.get_entry_list(login_context.session_id,module_name,"#{@module}.id='#{id}'","",0,"",size,0)
        @user_list
             
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: get_user_records call failed : " << e.message)
      end
      
    end  
    
    
    def create_new_contact(first_name,last_name,email_address)
     
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
        @newcontact=service.create_contact(user,password,first_name,last_name,email_address)
        @newcontact
      
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_contact call failed : " << e.message)
      end
      
    end
    
    
    def create_new_lead(first_name,last_name,email_address)
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
    
        @newlead=service.create_lead(user,password,first_name,last_name,email_address)
        @newlead
      
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_lead call failed : " << e.message)
      end
      
    end
    
    
    def create_new_account(name,phone,website)
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
        
        @newaccount=service.create_account(user,password,name,phone,website)
        @newaccount
      
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_account call failed : " << e.message)
      end
      
    end
    
    def create_new_opportunity(name,amount)
      begin
        service = connect
       
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
        
        @newopportunity=service.create_opportunity(user,password,name,amount)
        @newopportunity
      
      rescue Exception => e
        raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_opportunity : " << e.message)
      end
      
    end
    
    
    def create_new_case(name)
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
      
        @newcase=service.create_case(user,password,name)
        @newcase
      
      rescue Exception => e
          raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_case call failed : " << e.message)
      end
      
    end
    
    def create_new_project(name)
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
      
        @newproject=service.create_project(user,password,name)
        @newproject
      
      rescue Exception => e
          raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_project call failed : " << e.message)
      end
      
    end
    
    def create_new_projecttask(name,project_id)
      begin
        service = connect
        
        user = @login_context.login_user_name
        password = Digest::MD5.hexdigest(@login_context.login_password)
      
        @newprojecttask=service.create_projecttask(user,password,name,project_id)
        @newprojecttask
      
      rescue Exception => e
          raise AjubySugarcrmPipe.build_err_trace("#{ADAPTER_STRING_CONST}: create_new_projecttask call failed : " << e.message)
      end
      
    end
    
    def build_query_str_from_options(options, queried_obj_name)
      @query_str =""
      if options==nil
        @query_str = "*"
      else
        options.each {|option_element|
         @query_str = @query_str + "#{option_element}," 
        }
        @query_str = @query_str[0,@query_str.length-1]
      end
      @query_str = "select #{@query_str} from #{queried_obj_name}"
      @query_str  
    end  
    
    def get_login_options
      @service_call_options = Hash.new()
      @service_call_options['username'] = login_context.login_user_name
      @service_call_options['password'] = login_context.login_password
      @service_call_options
    end
      
    def set_post_login_data( login_result , service)
      login_context.session_id = login_result.id
      login_context.user_id = service.get_user_id(login_context.session_id)
    end

    def self.is_connection_failed(service_result)
      connection_failed = false
      if service_result !=nil
        if(service_result.code == AjubySoapBox::Codes::COULD_NOT_CONNECT)
          connection_failed = true
        else
          connection_failed = false
        end  
      end
      connection_failed
    end
   
    def connect
      #AjubyLogger.logInfo("header_handler_obj>> #{header_handler_obj} | session_id >> #{session_id}")
      @service_result = nil
      if (header_handler_obj == nil and login_context.session_id == nil)
        @service_result = login
      end
      
      if AjubySugarcrmPipe.is_connection_failed(@service_result)
        raise AjubySugarcrmPipe.build_err_trace("[ Connection failed " <<@service_result.connection_message << " ]")
      else
        post_login_connect
      end
        
    end
    
    def self.build_err_trace(err_msg)
      err_msg = "<br>&nbsp;-->"<<err_msg
      err_msg
    end
        
    def post_login_connect()
      AjubySoapBox.connect_w_header(login_context.wsdl_url, login_context.server_url, debug_soap, header_handler_obj)
    end
      
    def debug_soap
      if debug=='true'
         return 'true'
      else
         return 'false'
      end
    end
  
    def records_size
     @records_size
    end   

  
    def header_handler_obj
      @header_handler_obj
    end
      
    def debug
     @debug
    end   
   
    def login_context
      @login_context
    end  
    

  class LoginContext
    
    def initialize
        
    end
      
    def wsdl_url
      @wsdl_url
    end   

    def wsdl_url=(wsdl_url)
      @wsdl_url = wsdl_url
    end   
   
    def session_id
      @session_id
    end   

    def session_id=(session_id)
      @session_id = session_id
    end   

    def server_url
     @server_url
    end   

    def server_url=(server_url)
      @server_url = server_url
    end   
  
    def user_id
     @user_id
    end 

    def user_id=(user_id)
      @user_id = user_id
    end   

    def login_user_name
     @login_user_name
    end 

    def login_user_name=(login_user_name)
      @login_user_name = login_user_name
    end   

    def login_password
     @login_password
    end 

    def login_password=(login_password)
      @login_password = login_password
    end  
    
    def name
     @name
    end 

    def name=(name)
      @name = name
    end   
    
  end
      
  class PostLoginHeader 
    @@HEADER_NAME = "SessionHeader"
    @@HEADER_NAMESPACE = "http://www.sugarcrm.com/sugarcrm"
    
    def self.get_header(login_session_id)
      options = {"sessionId"=>[login_session_id, @@HEADER_NAMESPACE]}
      header_handler = AjubySoapBox::SOAPHeaderHandler.new(@@HEADER_NAME, @@HEADER_NAMESPACE, options)
      header_handler
    end  
    
  end   
  
end